#!/bin/sh
# PCP QA Test No. 1457
# Exercise HTTPS access to the PMWEBAPI(3).
#
# Copyright (c) 2019,2021-2022 Red Hat.
#

seq=`basename $0`
echo "QA output created by $seq"

. ./common.secure

_check_key_server
_check_valgrind
_check_tls

_cleanup()
{
    cd $here
    if $need_restore
    then
	need_restore=false
	_restore_config $PCP_SYSCONF_DIR/labels
	_restore_config $PCP_TLSCONF_PATH
	_sighup_pmcd
    fi
    $sudo rm -rf $tmp $tmp.*
}

status=1	# failure is the default!
need_restore=false
username=`id -u -n`
trap "_cleanup; exit \$status" 0 1 2 3 15

_filter_json()
{
    tee -a $seq_full > $tmp.unfiltered
    if [ -s $tmp.unfiltered ]
    then
	pmjson < $tmp.unfiltered > $tmp.filtered
	status=$?
	    if [ $status -eq 0 ]; then
	    cat $tmp.filtered | \
	    sed \
		-e '/"machineid": .*/d' \
		-e 's,"series": .*,"series": "SERIES",g' \
		-e 's,"context": .*,"context": "CONTEXT",g' \
		-e 's,"hostname": .*,"hostname": "HOSTNAME",g' \
		-e 's,"domainname": .*,"domainname": "DOMAINNAME",g' \
	    #end
	else
	    echo "Invalid JSON: $status"
	    cat $tmp.unfiltered
	    rm -f $tmp.context
	fi
    else
	echo "Botch: no output from curl"
    fi
}

_filter_port()
{
    sed \
        -e '/ ipv6 /d' \
	-e "s/ $port / PORT /g" \
    #end
}

# real QA test starts here
_save_config $PCP_SYSCONF_DIR/labels
_save_config $PCP_TLSCONF_PATH
need_restore=true

$sudo rm -rf $PCP_SYSCONF_DIR/labels/*
_sighup_pmcd || _exit 1

# creates a self-signed (insecure) certificate, so for testing only
_setup_tls
echo "[pmproxy]" >> $tmp.conf
echo "pcp.enabled = true" >> $tmp.conf
echo "http.enabled = true" >> $tmp.conf
echo "resp.enabled = true" >> $tmp.conf
echo "secure.enabled = true" >> $tmp.conf
echo "private_key = $tmp.tls/pcp.key" >> $tmp.conf
echo "certificates = $tmp.tls/pcp.crt" >> $tmp.conf

port=`_find_free_port`
mkdir -p $tmp.pmproxy/pmproxy
export PCP_RUN_DIR=$tmp.pmproxy
export PCP_TMP_DIR=$tmp.pmproxy

$valgrind_clean_assert pmproxy -f -l- --timeseries \
	-c $tmp.conf -p $port -U $username \
	>$tmp.valout 2>$tmp.valerr &
pid=$!

echo "valgrind pid: $pid" >>$seq_full
echo "pmproxy port: $port" >>$seq_full

# valgrind takes awhile to fire up
i=0
while [ $i -lt 40 ]
do
    $PCP_BINADM_DIR/telnet-probe -c localhost $port && break
    sleep 1
    i=`expr $i + 1`
done
if $PCP_BINADM_DIR/telnet-probe -c localhost $port
then
    echo "Startup took $i secs" >>$seq_full
else
    echo "Arrgh: valgrind failed start pmproxy and get port $port ready after 30 secs"
    echo "=== valgrind stdout ===" >> $seq_full
    cat $tmp.valout >> $seq_full
    echo "=== valgrind stderr ===" >> $seq_full
    cat $tmp.valerr >> $seq_full
    exit
fi

date >>$seq_full
echo "=== checking serial http operation ===" | tee -a $seq_full
for i in 1 2 3 4; do
    curl -Gs "http://localhost:$port/pmapi/metric?name=sample.long.ten" 2>$tmp.err$i >$tmp.out$i
done
for i in 1 2 3 4; do
echo === out$i === | tee -a $seq_full
_filter_json < $tmp.out$i
done

date >>$seq_full
echo "=== checking parallel http operation ===" | tee -a $seq_full
for i in 1 2 3 4; do
    curl -Gs "http://localhost:$port/pmapi/metric?name=sample.long.ten" 2>$tmp.err$i >$tmp.out$i & 2>/dev/null eval pid$i=$!
done
wait $pid1 $pid2 $pid3 $pid4
for i in 1 2 3 4; do
echo === out$i === | tee -a $seq_full
_filter_json < $tmp.out$i
done

date >>$seq_full
echo "=== checking serial https/TLS operation ===" | tee -a $seq_full
for i in 1 2 3 4; do
    curl -k -Gs "https://localhost:$port/pmapi/metric?name=sample.long.ten" 2>$tmp.err$i >$tmp.out$i
done
for i in 1 2 3 4; do
echo === out$i === | tee -a $seq_full
_filter_json < $tmp.out$i
done

date >>$seq_full
echo "=== checking parallel https/TLS operation ===" | tee -a $seq_full
for i in 1 2 3 4; do
    curl -k -Gs "https://localhost:$port/pmapi/metric?name=sample.long.ten" 2>$tmp.err$i >$tmp.out$i & 2>/dev/null eval pid$i=$!
done
wait $pid1 $pid2 $pid3 $pid4
for i in 1 2 3 4; do
echo === out$i === | tee -a $seq_full
_filter_json < $tmp.out$i
done

date >>$seq_full
echo "=== checking parallel mixed http and https/TLS operations ===" | tee -a $seq_full
for i in 1 3 5 7; do
    j=`expr $i + 1`
    curl -k -Gs "http://localhost:$port/pmapi/metric?name=sample.long.ten" 2>$tmp.err$i >$tmp.out$i & 2>/dev/null eval pid$i=$!
    curl -k -Gs "https://localhost:$port/pmapi/metric?name=sample.long.ten" 2>$tmp.err$j >$tmp.out$j & 2>/dev/null eval pid$j=$!
done
wait $pid1 $pid2 $pid3 $pid4 $pid5 $pid6 $pid7 $pid8
for i in 1 2 3 4 5 6 7 8; do
echo === out$i === | tee -a $seq_full
_filter_json < $tmp.out$i
done

echo "=== check pmproxy is running ==="
pminfo -v -h localhost@localhost:$port hinv.ncpu
if [ $? -eq 0 ]; then
    echo "pmproxy check passed"
else
    echo "pmproxy check failed"
fi

# valgrind takes awhile to shutdown too
pmsignal $pid >/dev/null 2>&1
pmsleep 3.5
echo "=== valgrind stdout ===" | tee -a $seq_full
cat $tmp.valout | _filter_valgrind

echo "=== valgrind stderr ===" | tee -a $seq_full
cat $tmp.valerr | _filter_pmproxy_log | _filter_port

# success, all done
status=0
exit
